package com.xxx.car.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xxx.car.constants.CarStatus;
import com.xxx.car.entity.TbUser;
import com.xxx.car.entity.TbUserCar;
import com.xxx.car.entity.vo.request.ReqUserCar;
import com.xxx.car.entity.vo.request.ReqUserCarAdminQuery;
import com.xxx.car.entity.vo.request.ReqUserCarQuery;
import com.xxx.car.entity.vo.response.RespUserCar;
import com.xxx.car.entity.vo.response.RespUserCarAdmin;
import com.xxx.car.mapper.ITbMapper;
import com.xxx.car.service.UserCarService;
import com.xxx.car.mapper.TbUserCarMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by xuwenjie on 2017/6/14.
 */
@Service
public class UserCarServiceImpl implements UserCarService {

    @Autowired
    private TbUserCarMapper tbUserCarMapper;

    @Autowired
    private ITbMapper iTbMapper;

    @Override
    public List<RespUserCar> query(ReqUserCarQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        return tbUserCarMapper.query(query).stream().map(e -> {
            RespUserCar respUserCar = new RespUserCar();
            BeanUtils.copyProperties(e, respUserCar);
            return respUserCar;
        }).collect(Collectors.toList());
    }

    @Override
    public RespUserCar getByIdAndUser(Integer carId, Integer userId) {
        TbUserCar userCar = tbUserCarMapper.getByIdAndUserId(carId, userId);
        if (userCar != null) {
            RespUserCar respUserCar = new RespUserCar();
            BeanUtils.copyProperties(userCar, respUserCar);
            return respUserCar;
        }
        return null;
    }

    @Override
    public void deleteByIdAndUser(Integer carId, Integer userId) {
        tbUserCarMapper.deleteByIdAndUserId(carId, userId);
    }

    @Override
    public void saveOrUpdate(ReqUserCar reqUserCar) {
        TbUserCar tbUserCar = new TbUserCar();
        BeanUtils.copyProperties(reqUserCar, tbUserCar);
        if (tbUserCar.getCarId() != null) {
            tbUserCar.setUpdateTime(new Date());
            tbUserCar.setCarStatus(CarStatus.WAIT_AUDIT);
            tbUserCarMapper.updateByPrimaryKeySelective(tbUserCar);
        } else {
            tbUserCar.setCarStatus(CarStatus.WAIT_AUDIT);
            tbUserCar.setCreateTime(new Date());
            tbUserCar.setUpdateTime(new Date());
            tbUserCar.setDefaultCar(false);
            tbUserCarMapper.insertSelective(tbUserCar);
        }

    }

    @Override
    public Page<RespUserCarAdmin> queryForAdmin(ReqUserCarAdminQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        Page<TbUserCar> page = (Page<TbUserCar>) tbUserCarMapper.queryForAdmin(query);
        if (!page.getResult().isEmpty()) {
            List<TbUser> users = iTbMapper.findUserByIds(page.stream().map(e -> e.getUserId()).collect(Collectors.toList()));
            List<RespUserCarAdmin> data = page.stream().map(e -> {
                RespUserCarAdmin respUserCarAdmin = new RespUserCarAdmin();
                BeanUtils.copyProperties(e, respUserCarAdmin);
                users.stream().filter(u->u.getId().equals(respUserCarAdmin.getUserId())).findFirst().ifPresent(x->respUserCarAdmin.setMobile(x.getMobile()));
                return respUserCarAdmin;
            }).collect(Collectors.toList());
            Page<RespUserCarAdmin> resp = new Page<>(page.getPageNum(), page.getPageSize());
            resp.addAll(data);
            resp.setTotal(page.getTotal());
            return resp;
        } else {
            return new Page<>(query.getPageNum(), query.getPageSize());
        }
    }

    @Override
    public PageInfo<TbUserCar> queryUserCarListForAdmin(ReqUserCarAdminQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<TbUserCar> tbUserCarList = tbUserCarMapper.queryForAdmin(query);
        return new PageInfo<>(tbUserCarList);
    }

    @Override
    public Map<Integer, Integer> statusGroupCount() {
        Map<Integer, Integer> res = new HashMap<>();
        tbUserCarMapper.statusGroupCount().forEach(e -> {
            Integer status = (Integer) e.get("car_status");
            Integer count = ((Long) e.get("count(0)")).intValue();
            res.put(status, count);
        });
        return res;
    }

    @Override
    public RespUserCarAdmin getForAdmin(Integer carId) {
        TbUserCar tbUserCar = tbUserCarMapper.selectByPrimaryKey(carId);
        if (tbUserCar != null) {
            RespUserCarAdmin car = new RespUserCarAdmin();
            BeanUtils.copyProperties(tbUserCar, car);
            iTbMapper.findUserByIds(Arrays.asList(car.getUserId())).stream().findFirst().ifPresent(e->car.setMobile(e.getMobile()));
            return car;
        }
        return null;
    }

    @Override
    public void audit(Integer carId, Boolean pass, String carErrMsg) {
        TbUserCar car = new TbUserCar();
        car.setCarId(carId);
        Date now = new Date();
        car.setAuditTime(now);
        car.setUpdateTime(now);
        if (pass) {
            car.setCarStatus(CarStatus.AUDIT_SUCCESS);
        } else {
            car.setCarStatus(CarStatus.AUDIT_FAIL);
            car.setCarErrMsg(carErrMsg);
        }
        tbUserCarMapper.updateByPrimaryKeySelective(car);
    }

    @Override
    public RespUserCar getUserDefaultCar(Integer userId) {
        TbUserCar car = tbUserCarMapper.getUserDefaultCar(userId).stream().findFirst().orElse(null);
        if (car != null) {
            RespUserCar res = new RespUserCar();
            BeanUtils.copyProperties(car, res);
            return res;
        }
        return null;
    }

    @Override
    @Transactional
    public void setDefaultCar(Integer userId, Integer carId) {
        tbUserCarMapper.clearDefaultByUserId(userId);
        tbUserCarMapper.setUserDefaultCar(userId, carId);
    }

    @Override
    public TbUserCar getCarByCarNo(String carNo) {
        return tbUserCarMapper.getCarByCarNo(carNo);
    }
}
